//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.tl.satoken.service;

import com.tl.satoken.domain.entity.Player;
import com.tl.satoken.listener.WebSocketEventListener;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

@Service
public class HeartbeatService {
    private static final Logger log = LoggerFactory.getLogger(HeartbeatService.class);
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    @Autowired
    private RoomService roomService;
    @Autowired
    private WebSocketEventListener webSocketEventListener;
    private final ScheduledExecutorService heartbeatScheduler = Executors.newScheduledThreadPool(1);

    public HeartbeatService() {
        log.info("启动心跳检测任务，每30秒检查一次");
        this.heartbeatScheduler.scheduleAtFixedRate(this::checkHeartbeat, 30L, 30L, TimeUnit.SECONDS);
    }

    private void checkHeartbeat() {
        long currentTime = System.currentTimeMillis();
        long timeoutThreshold = 3600000L;
        Map<String, Long> playerLastHeartbeat = this.webSocketEventListener.getPlayerLastHeartbeat();
        Map<String, Player> sessionPlayerMap = this.webSocketEventListener.getSessionPlayerMap();
        playerLastHeartbeat.entrySet().removeIf((entry) -> {
            String playerId = (String)entry.getKey();
            long lastHeartbeat = (Long)entry.getValue();
            if (currentTime - lastHeartbeat > timeoutThreshold) {
                log.warn("玩家 {} 心跳超时，强制下线", playerId);
                if (this.roomService.leaveRoom(playerId)) {
                    String roomId = this.findPlayerRoomId(playerId, sessionPlayerMap);
                    if (roomId != null) {
                        List<Player> remainingPlayers = this.roomService.getPlayersInRoom(roomId);
                        this.messagingTemplate.convertAndSend("/topic/room/" + roomId, remainingPlayers);
                        log.info("房间 {} 剩余玩家数量: {}", roomId, remainingPlayers.size());
                    }
                }

                sessionPlayerMap.entrySet().removeIf((sessionEntry) -> playerId.equals(((Player)sessionEntry.getValue()).getId()));
                return true;
            } else {
                return false;
            }
        });
    }

    private String findPlayerRoomId(String playerId, Map<String, Player> sessionPlayerMap) {
        return (String)sessionPlayerMap.values().stream().filter((p) -> playerId.equals(p.getId())).map(Player::getRoomId).findFirst().orElse((String) null);
    }
}
